package org.bigk.invoices.utils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bigk.invoices.model.PaginatedBean;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.criterion.Projections;

public class HibernateUtils {
	/**
	 * Logger for this class
	 */
	private static final Log logger = LogFactory.getLog(HibernateUtils.class);

	private static final SessionFactory sessionFactory = initSessionFactory();
	
	private static SessionFactory initSessionFactory() {
		if (logger.isDebugEnabled()) {
			logger.debug("initSessionFactory() - start");
		}

		SessionFactory returnSessionFactory = null;
		try {
			returnSessionFactory =
				new AnnotationConfiguration().configure().buildSessionFactory();
		} catch (Throwable ex) {
			logger.error("initSessionFactory()", ex);
		}
		
		if (logger.isDebugEnabled()) {
			logger.debug("initSessionFactory() - end - return value="
					+ returnSessionFactory);
		}
		return returnSessionFactory;
    }

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	
    public static Session getSession() throws HibernateException {
		return sessionFactory.openSession();
	}
    
    public static Session getCurrentSession() throws HibernateException {
		return sessionFactory.getCurrentSession();
	}

    public static PaginatedBean updateStats(Criteria crit, PaginatedBean pBean)
			throws HibernateException {
		if (logger.isDebugEnabled()) {
			logger.debug("updateStats(Criteria crit=" + crit
					+ ", PaginatedBean pBean=" + pBean + ") - start");
		}

		crit.setProjection(Projections.rowCount());
		Integer uniqueResult = (Integer) crit.uniqueResult();
		if (logger.isDebugEnabled()) {
			logger.debug("updateStats(Criteria, PaginatedBean) - uniqueResult=" + uniqueResult);
		}
		
		int totalRecords = uniqueResult == null ? 0 : uniqueResult.intValue();
		crit.setProjection(null);
		crit.setResultTransformer(Criteria.ROOT_ENTITY);
		int totalPages = (int) Math.ceil(
				(double) totalRecords / (double) pBean.getPaginatedPageSize().intValue());
		pBean.setTotalRecords(Integer.valueOf(totalRecords));
		pBean.setTotalPages(Integer.valueOf(totalPages));
		
		if (logger.isDebugEnabled()) {
			logger.debug("updateStats(Criteria, PaginatedBean) - end - return value=" + pBean);
		}
		return pBean;
	}

}
